

import java.util.Arrays;


public class PrimaryExpr extends MultiplicativeExpr {

	// which type, if constant: NM, BL, ST, ID
	int type;
	String lexeme;
	// Whether it is constant, callExpr or (expression)
	boolean[] flags = new boolean[2];
	// one of the four types: NM, BL, ST, ID
	public static final int constant_t = 0;
	public static final int expression_t = 1;
	Expression expression;

	public PrimaryExpr() {

	}

	public PrimaryExpr(String lexeme) {
		this.lexeme = lexeme;
	}

	public PrimaryExpr(Expression e) {
		expression = e;
	}

	public void setLexeme(String s) {
		lexeme = s;
	}

	public void setType(int type) {
		this.type = type;
	}

	public void setFlag(int flag) {
		Arrays.fill(flags, false);
		flags[flag] = true;
	}

	public void check() throws SemanticException {
		SymbolTable table = SymbolTable.getInstance();
		// If variable not declared or declared but not as variable
		if (flags[constant_t]) {
			switch (type) {
			case Type.ID: {
				if (!table.contains(lexeme) || table.contains(lexeme)
						&& table.get(lexeme).category != Entry.VARIABLE)
					throw new SemanticException(
							"Variable not declared before using in expression: "
									+ lexeme);
			}
				break;
			default:
				break;
			}
		} else {
			expression.check();
		}
	}

	public int checkType() throws SemanticException {
		if (flags[constant_t]) {
			switch (type) {
			case Type.ID: {
				Entry e = SymbolTable.getInstance().get(lexeme);
				return e.type;
			}
			default:
				// it will be either NM,BL,ST
				return type;
			}
		}
		return expression.checkType();
	}

	public String toString() {
		if (flags[constant_t]) {
			return lexeme + "\n";
		}
		// expression
		return expression.toString();

	}
}
